package com.sds.sweng.swat.miplatform.ui.design.models.area.sub;

import java.util.ArrayList;
import java.util.List;

import org.codehaus.jackson.annotate.JsonIgnore;

import com.sds.sweng.swat.miplatform.ui.design.models.MiplatformComponent;


public class HorizontalSubAreaContainer extends SubArea {

	public static final int
		GAP = 8,
		MAX_CHILD_COUNT = 3;

	protected List<Integer> areaWidths = new ArrayList<Integer>();

	protected SubArea[] initSubAreas;
	protected int[] initSubAreaWidths;

	public HorizontalSubAreaContainer() {

	}

	public HorizontalSubAreaContainer(SubArea initSubArea) {
		this(new SubArea[] {initSubArea}, new int[] {-1});
	}

	public HorizontalSubAreaContainer(SubArea[] initSubAreas, int[] initSubAreaWidth) {
		this.initSubAreas = initSubAreas;
		this.initSubAreaWidths = initSubAreaWidth;
	}

	public void init() {
		if (initSubAreas == null)
			return;

		for (int i=0;i<initSubAreas.length;i++) {
			addSubArea(initSubAreas[i], initSubAreaWidths[i]);
		}

		initSubAreas = null;
		initSubAreaWidths = null;
	}

	public HorizontalSubAreaContainer clone() {
		HorizontalSubAreaContainer clone = (HorizontalSubAreaContainer) super.clone();
		clone.setAreaWidths(getAreaWidths());

		for (MiplatformComponent child : getChildren()) {
			clone.addChild(child.clone());
		}

		return clone;
	}

	@JsonIgnore
	public int getAreaWidth(SubArea subArea) {
		return areaWidths.get(getChildren().indexOf(subArea)) + (getChildren().indexOf(subArea) < getChildren().size()-1 ? 1 : 2);
	}

	@JsonIgnore
	public int getContentsWidth(SubArea subArea) {
		return areaWidths.get(getChildren().indexOf(subArea)) - (getChildren().indexOf(subArea) < getChildren().size()-1 ? GAP : 0);
	}

	public void addSubArea(SubArea subArea) {
		if (getChildren().size() == 0)
			addSubArea(subArea, -1);
	}

	public void addSubArea(SubArea subArea, int width) {
		if (getChildren().size() == 0) {
			width = getWidth() - 2;
		} else if (getChildren().size() == MAX_CHILD_COUNT) {
			return;
		} else {
			if (width == SubArea.DEFAULT_WIDTH)
				width = subArea.getDefaultWidth();

			if (width < 0)
				return;

			int requiredWidth = width;

			for (int i=getChildren().size()-1;i>=0;i--) {
				SubArea child = (SubArea) getChildren().get(i);
				if (child.getRemainWidth() > 0) {
					requiredWidth -= child.getRemainWidth();
				}

				if (requiredWidth < 1)
					break;
			}

			if (requiredWidth > 0)
				return;

			requiredWidth = width;

			for (int i=getChildren().size()-1;i>=0;i--) {
				SubArea child = (SubArea) getChildren().get(i);
				if (child.getRemainWidth() > 0) {
					int dif = child.getRemainWidth() - requiredWidth;
					int childRemainWidth = child.getRemainWidth();

					setAreaWidthInternal(child, child.getWidth() - (dif > -1 ? requiredWidth : child.getRemainWidth()));
					requiredWidth -= childRemainWidth;
				}

				if (requiredWidth < 1)
					break;
			}
		}

		subArea.setWidth(width);
		areaWidths.add(width);
		addChild(subArea);
	}

	private void setAreaWidthInternal(SubArea subArea, int width) {
		subArea.setWidth(width);
		areaWidths.set(getChildren().indexOf(subArea), width);
	}

	@JsonIgnore
	public void setAreaWidth(SubArea subArea, int width) {
		if (width == SubArea.DEFAULT_WIDTH)
			width = subArea.getDefaultWidth();

		if (width < 0)
			return;

		int requiredWidth = width - subArea.getWidth();

		for (int i=getChildren().size()-1;i>=0;i--) {
			SubArea child = (SubArea) getChildren().get(i);

			if (child.equals(subArea))
				continue;

			if (child.getRemainWidth() > 0) {
				requiredWidth -= child.getRemainWidth();
			}

			if (requiredWidth < 1)
				break;
		}

		if (requiredWidth > 0)
			return;

		requiredWidth = width - subArea.getWidth();

		for (int i=getChildren().size()-1;i>=0;i--) {
			SubArea child = (SubArea) getChildren().get(i);

			if (child.equals(subArea))
				continue;

			if (child.getRemainWidth() > 0) {
				int dif = child.getRemainWidth() - requiredWidth;
				int childRemainWidth = child.getRemainWidth();

				setAreaWidthInternal(child, child.getWidth() - (dif > -1 ? requiredWidth : child.getRemainWidth()));
				requiredWidth -= childRemainWidth;
			}

			if (requiredWidth < 1)
				break;
		}

		subArea.setWidth(width);
		areaWidths.set(getChildren().indexOf(subArea), width);
	}

	public void removeSubArea(SubArea subArea) {
		areaWidths.remove(getChildren().indexOf(subArea));

		removeChild(subArea);
	}

	@Override
	public boolean isEmpty() {
		for (int i=0;i<getChildren().size();i++) {
			if (!((SubArea) getChildren().get(i)).isEmpty())
				return false;
		}

		return true;
	}

	@Override
	public int getRemainWidth() {
		return 0;
	}

	public boolean isFixed() {
		return true;
	}

	public List<Integer> getAreaWidths() {
		return areaWidths;
	}

	public void setAreaWidths(List<Integer> areaWidths) {
		this.areaWidths = areaWidths;
	}

	@Override
	public int getRequireWidth() {
		return getWidth();
	}

}
